package net.jcip.chapter4;

import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;

import net.jcip.annotations.*;

/**
 * ListHelder
 * <p/>
 * Examples of thread-safe and non-thread-safe implementations of
 * put-if-absent helper methods for List
 *
 * @author Brian Goetz and Tim Peierls
 */

@NotThreadSafe
class BadListHelper <E> {

    public List<E> list = Collections.synchronizedList(new ArrayList<E>());


    /**
     * 为什么这种方式不能实现线程安全性？毕竞，putIfAbsent已经声明为synchronized类型的
     * 变量，对不对？问题在于在错误的锁上进行了同步。无论Lst使用哪一个锁来保护它的状态，
     * 可以确定的是，这个锁并不是ListHelper上的锁。ListHelper只是带来了同步的假象，尽管所
     * 有的链表操作都被声明为synchronized,但却使用了不同的锁，这意味着putIfAbsent相对于
     * List的其他操作来说并不是原子的，因此就无法确保当putIfAbsent执行时另一个线程不会修改
     * 链表。
     *
     * */
    public synchronized boolean putIfAbsent(E x) {
        boolean absent = !list.contains(x);
        if (absent){
            list.add(x);
        }
        return absent;
    }
}

@ThreadSafe
class GoodListHelper <E> {
    public List<E> list = Collections.synchronizedList(new ArrayList<E>());

    public boolean putIfAbsent(E x) {
        synchronized (list) {
            boolean absent = !list.contains(x);
            if (absent){
                list.add(x);
            }
            return absent;
        }
    }
}


class Client{


    public static void main(String[] args){


        ExecutorService executorService = Constant4.executorService;

        CountDownLatch countDownLatch = Constant4.countDownLatch;


    }


}


